/*
 *  /linux-3.0.8/drivers/spi/gt210_nrf2401.h
*/
#ifndef __GT2440_NRF2401_H
#define __GT2440_NRF2401_H
#include <linux/types.h>

/***** plat data structure *****/
struct gt210_nrf2401_platdata{
	/* nrf2401 chip used regs sets */
	unsigned char	en_aa;		/* 0x00: auto ack */
	unsigned char	en_rxaddr;	/* 0x01: rx addr enable */
	unsigned char	setup_aw;		/* 0x02: addr width */
	unsigned char	setup_retr;		/* 0x03: retransmit */
	unsigned char	rf_ch;		/* 0x04: channel */
	unsigned char	rf_setup;	/* 0x05: setup: rf baudrate */
							/* 0x1-0x0f: rx addr */
							/* 0x10: tx addr */
	unsigned char	rx_pw_p0;		/* 0x11: pipe width  */
	unsigned char	rx_pw_p1;		/* 0x12: */
	unsigned char	rx_pw_p2;		/* 0x13: */
	unsigned char	rx_pw_p3;		/* 0x14: */
	unsigned char	rx_pw_p4;		/* 0x15: */
	unsigned char	rx_pw_p5;		/* 0x16: */
	
	unsigned char	dynpld;	/* 0x1c: dynamic payload */
	unsigned char	feature;	/* 0x1d:  */

	/* chip enable , irq pin */
	unsigned long	ce_pin;

	unsigned long	irq;
	unsigned long	irq_pin;
	unsigned long	irq_flags;

	int (*init_pin)(struct gt210_nrf2401_platdata *pdata);
	void (*exit_pin)(struct gt210_nrf2401_platdata *pdata);
	
	void (*set_cepin)(struct gt210_nrf2401_platdata *pdata);
	void (*clear_cepin)(struct gt210_nrf2401_platdata *pdata);

};

/***** driver data structure *****/
#define NRF2401_ADDR_NUM 6
#define NRF2401_ADDR_LEN 5
#define NRF2401_PIPE_LEN 32

#define NRF2401_PIPE_STATE_NONE (1<<0)
#define NRF2401_PIPE_STATE_SETTING (1<<1)
#define NRF2401_PIPE_STATE_SETTED (1<<2)


enum nrf2401_addr_num{
	NRF2401_ADDR_0,
	NRF2401_ADDR_1,
	NRF2401_ADDR_2,
	NRF2401_ADDR_3,
	NRF2401_ADDR_4,
	NRF2401_ADDR_5,
};

enum nrf2401_pipe_mode{
	NRF2401_PIPE_TX_MODE,
	NRF2401_PIPE_RX_MODE,
};
enum nrf2401_pipe_state{
	NRF2401_PIPE_SETTING,
	NRF2401_PIPE_SETTED,
};

struct gt210_nrf2401_pbuf{
	struct list_head list;

	int addr_num;
	int mseconds;
	
	u8 pipe_buf[NRF2401_PIPE_LEN];
};

struct gt210_nrf2401_pipe{
	struct list_head head;
	
	struct gt210_nrf2401_info *info;
	
	struct nrf2401_ioc_transfer *xfer;
	
	struct gt210_nrf2401_pbuf *xbuf;
	
	struct gt210_nrf2401_pbuf *pbuf;
	
	int error;

	
	int retx_limits;
	int delay_ms;
	
	int has_packets;
	
	int packets;
	
	int err_packets;
	
	int (*callback)(struct gt210_nrf2401_pipe *pipe, 
				struct gt210_nrf2401_pbuf *pbuf);
	
	struct work_struct work;
	
	struct completion done;
	
	struct timer_list timer;
	
	enum nrf2401_addr_num		addr_num;
	enum nrf2401_pipe_mode mode;
	
	
	spinlock_t 	lock; /* for pbuf list */
	
	struct mutex 	mutex; /* for structure  */
	
	u8	addr[NRF2401_ADDR_LEN];
};

struct gt210_nrf2401_info{
	struct list_head	device_entry;
	struct spi_device	*spi_dev;

	struct device	*dev; /* it is self */
	
	struct gt210_nrf2401_platdata *pdata;

	unsigned char	name[32];
	unsigned		irq;
	unsigned		users;

	dev_t			devt;
	spinlock_t		spi_lock;
	
	struct mutex		buf_lock;
	
	spinlock_t	pipe_lock;
	
	unsigned long pipe_state;
	
	struct work_struct irq_work;

	struct gt210_nrf2401_pipe *tx_pipe;
	struct gt210_nrf2401_pipe *rx_pipe[NRF2401_ADDR_NUM];

};




// SPI(nRF24L01) commands
#define READ_REG1        0x00  // Define read command to register
#define WRITE_REG1       0x20  // Define write command to register
#define RD_RX_PLOAD     0x61  // Define RX payload register address
#define WR_TX_PLOAD     0xA0  // Define TX payload register address
#define FLUSH_TX        0xE1  // Define flush TX register command
#define FLUSH_RX        0xE2  // Define flush RX register command
#define REUSE_TX_PL     0xE3  // Define reuse TX payload register command
#define NOP             0xFF  // Define No Operation, might be used to read status register

//***************************************************//
// SPI(nRF24L01) registers(addresses)
#define CONFIG          0x00  // 'Config' register address
#define EN_AA           0x01  // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR       0x02  // 'Enabled RX addresses' register address
#define SETUP_AW        0x03  // 'Setup address width' register address
#define SETUP_RETR      0x04  // 'Setup Auto. Retrans' register address
#define RF_CH           0x05  // 'RF channel' register address
#define RF_SETUP        0x06  // 'RF setup' register address
#define STATUS          0x07  // 'Status' register address
#define OBSERVE_TX      0x08  // 'Observe TX' register address
#define CD              0x09  // 'Carrier Detect' register address
#define RX_ADDR_P0      0x0A  // 'RX address pipe0' register address
#define RX_ADDR_P1      0x0B  // 'RX address pipe1' register address
#define RX_ADDR_P2      0x0C  // 'RX address pipe2' register address
#define RX_ADDR_P3      0x0D  // 'RX address pipe3' register address
#define RX_ADDR_P4      0x0E  // 'RX address pipe4' register address
#define RX_ADDR_P5      0x0F  // 'RX address pipe5' register address
#define TX_ADDR         0x10  // 'TX address' register address
#define RX_PW_P0        0x11  // 'RX payload width, pipe0' register address
#define RX_PW_P1        0x12  // 'RX payload width, pipe1' register address
#define RX_PW_P2        0x13  // 'RX payload width, pipe2' register address
#define RX_PW_P3        0x14  // 'RX payload width, pipe3' register address
#define RX_PW_P4        0x15  // 'RX payload width, pipe4' register address
#define RX_PW_P5        0x16  // 'RX payload width, pipe5' register address
#define FIFO_STATUS     0x17  // 'FIFO Status Register' register address


/***** nrf2401 cmd and s50 cmd and regs *****/

#define SPICHAR_MAJOR			158	/* assigned */
#define N_SPI_MINORS			32	/* ... up to 256 */

#define SPI_DEVICE_NAME "nrf2401"




/***** nrf2401 ops function declare ****/
static int gt210_nrf2401_write_reg (struct gt210_nrf2401_info *info,
								unsigned char reg, unsigned char value);
static int gt210_nrf2401_read_reg (struct gt210_nrf2401_info *info,
								unsigned char reg,unsigned char *value);
static int gt210_nrf2401_read_status(struct gt210_nrf2401_info *info,
								unsigned char reg,unsigned char *value);
static int gt210_nrf2401_write_buf(struct gt210_nrf2401_info *info,
								unsigned char reg, unsigned char *buf, 
								unsigned char len);
static int gt210_nrf2401_read_buf(struct gt210_nrf2401_info *info,
								unsigned char reg, unsigned char *buf, 
								unsigned char len);


static irqreturn_t gt210_nrf2401_irq(int irq, void *dev_id);
static int gt210_nrf2401_tx_callback(struct gt210_nrf2401_pipe *pipe, 
				struct gt210_nrf2401_pbuf *pbuf);
static int gt210_nrf2401_rx_callback(struct gt210_nrf2401_pipe *pipe, 
				struct gt210_nrf2401_pbuf *pbuf);

static long gt210_nrf2401_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
static int gt210_nrf2401_open(struct inode *inode, struct file *filp);
static int gt210_nrf2401_release(struct inode *inode, struct file *filp);




/***** debug  *****/
#define GT210_NRF2401_DEBUG
#ifdef GT210_NRF2401_DEBUG
#define dprintk printk
#else
#define dprintk(...)
#endif

//#define GT210_NRF2401_TEST


#endif

